package abaco.gui;

import java.awt.BorderLayout;
import java.awt.Component;
import java.util.HashMap;

import javax.swing.JPanel;
import javax.swing.JPopupMenu;

import abaco.Symbol;
import abaco.gui.textfield.listener.FocusListener;
import abaco.gui.textfield.listener.MouseListener;
import abaco.symbol.Text;

public class Drawer {
	private static HashMap<Symbol, Panel> panels = new HashMap<Symbol, Panel>();
	private Symbol symbol = null;
	private Panel panel = null;

	public Drawer(Symbol symbol) {
		this.symbol = symbol;
		if (panels.containsKey(symbol)) {
			panel = panels.get(symbol);
		} else {
			panel = new Panel(symbol);
			panels.put(symbol, panel);
			panel.addMouseListener(new MouseListener(panel));
			panel.addFocusListener(new FocusListener(panel));
			symbol.buildPanel(panel);
		}
	}
	
	public Symbol getSymbol() {
		return symbol;
	}

	public Panel getPanel() {
		return panel;
	}

	public void draw(JPanel panel) {
		panel.add(this.panel, BorderLayout.SOUTH);
		refresh();
	}

	public void remove() {
		Component parent = panel.getParent();
		if (parent instanceof JPanel) {
			if (parent instanceof Panel) {
				// when panel parent is an equation editor panel then current
				// symbol is replaced to a text entry
				replace(new Text());
			} else {
				// just remove panel from another one
				((JPanel) parent).remove(panel);
			}
		}
	}

	public void replace(Symbol newSymbol) {
		Symbol parent = symbol.getSymbolParent();
		if (null != parent) {
			// change parent child
			String name = parent.getSymbolChildName(symbol);
			parent.setSymbolChild(newSymbol, name);
			(new Drawer(parent)).refresh();
		} else {
			// has no parent! the trick is to reference current panel to new
			// symbol, and then to remove the reference to current symbol,
			// create a new drawer, so then refresh it
			panels.put(newSymbol, panel);
			panels.remove(symbol);
			(new Drawer(newSymbol)).refresh();
		}
	}

	public void refresh() {
		panel.removeAll();
		symbol.buildPanel(panel);
		panel.refreshFontSize();
		panel.revalidate();
	}
}
